package yang;


import javax.swing.*;
import java.io.File;
import java.util.ArrayList;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

public class yang {
    public static <MP3Player> void main(String[] args) {
        JFrame frame = new JFrame("羊了个羊");
        JPanel panel = new JPanel();
        JLabel background = new JLabel(new ImageIcon("yang01/res/背景.jpg"));
        panel.setLayout(null);
        background.setSize(480, 800);
        background.setLocation(0, 0);
        panel.add(background);


        // 创建卡牌
        // ArrayList<JButton> cards = createCards(6, 25); //150
        ArrayList<JButton> cards = createCards(12, 12); //144
        //ArrayList<JButton> cards = createCards(9, 16); //144
        print(cards);

        //洗牌
        shuffle(cards);
        print(cards);

        //摆牌
        postForCards(cards, panel, 7, 7, 30, 100, 0);
        print(cards);
        postForCards(cards, panel, 6, 6, 60, 130, 49);
        print(cards);
        postForCards(cards, panel, 5, 7, 30, 160, 49 + 36);
        print(cards);
        postForCards(cards, panel, 6, 6, 60, 190, 49 + 36 + 35);
        print(cards);

        //检查牌的叠压关系
        checkCovered(cards);
        print(cards);

        //创建槽子trough
        ArrayList<JButton> trough = new ArrayList<>();
        //为每个牌添加点击事件
        addClickAction(cards, trough, panel);

        frame.add(panel);
        frame.setSize(502, 852);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setIconImage(new ImageIcon("yang01/res/羊.jpg").getImage());
//            MP3Player player = new MP3Player(new File("res/背景音乐.mp3"));
//            player.setRepeat(true);
        //player.play();
    }

    public static void addClickAction(ArrayList<JButton> cards,
                                      ArrayList<JButton> trough,
                                      JPanel panel) {
        for (JButton card : cards) {
            card.addActionListener(e -> {
                //System.out.println("OK");
                //e 称为事件对象，其中包含事件发生时候的信息。点击谁，时间，点击坐标
                //Source 来源，这里是指被点击的卡牌 // current 当前的
                JButton current = (JButton) e.getSource();
                System.out.println(current.getName());
                if (trough.size() == 7) { //槽子满了！
                    //显示一个对话框，提示用户，不能完了！
                    //show 显示 Message消息 Dialog对话框
                    // 第一个参数，遮挡位置，第二个参数消息内容
                    JOptionPane.showMessageDialog(panel, "槽子满，没得玩了！");
                    return;
                }
                //添加牌到槽子
                addCardToTrough(current, trough, cards, panel);
                checkCovered(cards);
            });
        }
    }

    // static java.util.Timer timer = new Timer();

    /**
     * 将选定的牌添加到槽子中
     *
     * @param current 被选定的当前牌
     * @param trough  槽子
     * @param cards   屏幕上方的一堆牌
     */
    public static void addCardToTrough(JButton current,
                                       ArrayList<JButton> trough,
                                       ArrayList<JButton> cards,
                                       JPanel panel) {
        Timer timer = new Timer();
        //从上方一堆牌中删除当前被点击的牌
        cards.remove(current);
        //找到位置，然后插入到下方槽子
        int index = 0;
        for (; index < trough.size(); index++) {
            JButton card = trough.get(index);
            if (card.getName().equals(current.getName())) {
                break;
            }
        }
        trough.add(index, current);
        //去除(remove)牌的点击事件, 加到下方槽子就不能被点击了
        current.removeActionListener(current.getActionListeners()[0]);
        int i = index;
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                timer.cancel();
                //更新槽子中每个牌的显示位置
                for (int i = 0; i < trough.size(); i++) {
                    JButton c = trough.get(i);
                    c.setLocation(20 + i * 62, 640);
                }
                panel.updateUI();
                //消除连续的3牌
                if (i + 2 < trough.size()) {
                    JButton nextNextCard = trough.get(i + 2);
                    if (current.getName().equals(nextNextCard.getName())) {
                        JButton c1 = trough.remove(i);
                        JButton c2 = trough.remove(i);
                        JButton c3 = trough.remove(i);
                        panel.remove(c1);//从面板上删除影像
                        panel.remove(c2);//从面板上删除影像
                        panel.remove(c3);//从面板上删除影像
                        //更新槽子中每个牌的显示位置
                        for (int i = 0; i < trough.size(); i++) {
                            JButton c = trough.get(i);
                            c.setLocation(20 + i * 62, 640);
                        }
                        panel.updateUI();
                    }
                }
            }
        }, 380);
        final int x1 = current.getX();
        final int y1 = current.getY();
        int dx = (20 - x1) / 10;
        int dy = (640 - y1) / 10;

        timer.schedule(new TimerTask() {
            int step = 0;

            @Override
            public void run() {
                step++;
                int x = x1 + step * dx;
                int y = x1 + step * dy;
                current.setLocation(x, y);
                panel.updateUI();
            }
        }, 0, 38);

    }

    /**
     * 检查牌的叠压关系：
     * - 如果一个牌被后续牌压住，则这个牌是下方牌
     * 实现步骤： 假设一个牌是上方牌，检查这个牌的后续牌是否被压住，
     * 如果压住则设置禁用
     *
     * @param cards
     */
    public static void checkCovered(ArrayList<JButton> cards) {
        for (int i = 0; i < cards.size(); i++) {
            //i 代表当前牌的序号位置
            JButton bottom = cards.get(i);
            bottom.setEnabled(true); //设置牌为允许状态, 也就是上方牌
            //从这个位置开始，查找后续所有的牌 是否在当前牌的上方
            for (int j = i + 1; j < cards.size(); j++) {
                //j 代表当前牌i的后续牌序号
                JButton top = cards.get(j);
                if (covered(top, bottom)) {
                    //被压住的牌需要设置为 被压住（禁用！）
                    bottom.setEnabled(false);
                    //发现bottom被压住，就不需要检查后续牌是否压住了bottom，结束j循环
                    break;
                }
            }
        }
    }

    /**
     * 两个卡牌的关系，top是否压住了bottom
     *
     * @param top    上方牌
     * @param bottom 下方牌
     * @return 如果压住了就返回 true
     */
    public static boolean covered(JButton top, JButton bottom) {
        int x1 = bottom.getX() - 59;
        int x2 = bottom.getX() + 59;
        int y1 = bottom.getY() - 60;
        int y2 = bottom.getY() + 60;
        return (top.getX() > x1 && top.getX() < x2) &&
                (top.getY() > y1 && top.getY() < y2);
    }

    public static void postForCards(ArrayList<JButton> cards,
                                    JPanel panel,
                                    int rows, int cols,
                                    int x, int y,
                                    int offset) {
        for (int i = 0; i < rows * cols; i++) {
            if (i + offset == cards.size()) {
                return;
            }
            JButton card = cards.get(i + offset);
            card.setLocation(x + i % cols * 59, y + i / cols * 60);
            panel.add(card, 0);
        }
    }

    public static void shuffle(ArrayList<JButton> cards) {
        Random random = new Random();
        for (int i = cards.size() - 1; i >= 1; i--) {
            cards.set(i, cards.set(random.nextInt(i), cards.get(i)));
        }
    }

    public static void print(ArrayList<JButton> cards) {
        System.out.println(cards.size());
        for (int i = 0; i < cards.size(); i++) {
            JButton card = cards.get(i);
            System.out.print(card.getName() +
                    "[" + card.getX() + "," + card.getY() + "]" + card.isEnabled() + " ");
            if ((i + 1) % 5 == 0) {
                System.out.println();
            }
        }
        System.out.println();
    }

    /**
     * @param round
     * @param types 类型： 1 ~ 25
     * @return
     */
    public static ArrayList<JButton> createCards(int round, int types) {
        String[] names = {"兔子", "刷子", "剪刀", "南瓜", "奶瓶", "帽子", "干草",
                "手套", "月饼", "树", "树桩", "栗子", "毛线", "水桶",
                "火堆", "白菜", "耙子", "苹果", "草", "萝卜", "蜜蜂",
                "酒坛", "铃铛", "面具", "饭团"};
        ArrayList<JButton> cards = new ArrayList<>();
        for (int i = 0; i < round; i++) {
            for (int j = 0; j < types; j++) {
                String name = names[j];
                String filename = "yang01/res/" + name + ".png";
                String filename2 = "yang01/res/" + name + "2.png";
                JButton card = new JButton(new ImageIcon(filename));
                card.setName(name);
                card.setDisabledIcon(new ImageIcon(filename2));
                card.setSize(59, 66);
                card.setContentAreaFilled(false);
                card.setBorderPainted(false);
                cards.add(card);
            }
        }
        return cards;
    }
}

